package org.eoti.io.xls;

/**
 * The MIT License
 * <p/>
 * Copyright (c) 2009 Malachi de AElfweald (malachid@gmail.com)
 * <p/>
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * <p/>
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 * Software.
 * <p/>
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;

public class XLSColumn
{
	protected HSSFSheet sheet;
	protected int columnNum;
	protected String columnTitle = "";
	protected CellHandler<?> handler;

	public XLSColumn(HSSFSheet sheet, int columnNum)
	{
//		System.out.format("Loading %s...", columnNum);
		this.sheet = sheet;
		this.columnNum = columnNum;
		HSSFCell cell = sheet.getRow(0).getCell((short)columnNum);
		if(cell != null)
			this.columnTitle = cell.getStringCellValue();

		handler = getCellHandler(determineCellType());
//		System.out.format("%s is TYPE:%s\n", columnTitle, handler.getClass().getName());
	}

	public Object getValue(int rowNum)
	{
		try{
			return handler.getValue(rowNum);
		} catch(Exception e){
			// sometimes, they aren't consistent for the entire column
			try{
				HSSFCell cell = getCell(rowNum);
				int cellType = cell.getCellType();
				CellHandler<?> tmpHandler = getCellHandler(cellType);
				return tmpHandler.getValue(rowNum);
			} catch(Exception e2){
				System.err.format("Error: %s\n", e2.getMessage());
				e.printStackTrace();
			}
		}

		return null;
	}

	public String getString(int rowNum)
	{
		try{
			return handler.getString(rowNum);
		} catch(Exception e){
			// sometimes, they aren't consistent for the entire column
			try{
				HSSFCell cell = getCell(rowNum);
				int cellType = cell.getCellType();
				CellHandler<?> tmpHandler = getCellHandler(cellType);
				return tmpHandler.getString(rowNum);
			} catch(Exception e2){
				System.err.format("Error: %s\n", e2.getMessage());
				e.printStackTrace();
			}
		}

		return "";
	}

	protected CellHandler<?> getCellHandler(int cellType)
	{
		if(cellType == HSSFCell.CELL_TYPE_STRING) return new StringHandler(this);
		if(cellType == HSSFCell.CELL_TYPE_BLANK) return new CellHandler(this);
		if(cellType == HSSFCell.CELL_TYPE_BOOLEAN) return new BooleanHandler(this);
//		if(cellType == HSSFCell.CELL_TYPE_ERROR) return  new ErrorHandler(this);
		if(cellType != HSSFCell.CELL_TYPE_NUMERIC) return new CellHandler(this);
		if(columnTitle.contains("Date")) return new DateHandler(this);
		if(columnTitle.contains("Time")) return new TimeHandler(this);
		if(columnTitle.contains("Amt")) return new CurrencyHandler(this);
		if(columnTitle.contains("Amount")) return new CurrencyHandler(this);
		if(columnTitle.contains("Balance")) return new CurrencyHandler(this);
		if(columnTitle.contains("Price")) return new CurrencyHandler(this);
		if(columnTitle.contains("Value")) return new CurrencyHandler(this);
		if(columnTitle.contains("Property Tax")) return new CurrencyHandler(this);
		return new NumericHandler(this);
	}

	public int determineCellType()
	{
		int lastRow = sheet.getLastRowNum();
		for(int rowNum=1; rowNum<=lastRow; rowNum++)
		{
			HSSFCell cell = getCell(rowNum);
			int cellType = cell.getCellType();
			if(cellType != HSSFCell.CELL_TYPE_BLANK)
				return cellType;
		}

		return HSSFCell.CELL_TYPE_BLANK;
	}

	public HSSFCell getCell(int rowNum)
	{
		HSSFRow row = sheet.getRow(rowNum);
		HSSFCell cell = row.getCell((short)columnNum);
		if(cell == null)
		{
			cell = row.createCell((short)columnNum);
			cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
		}
		return cell;
	}

	public String toString(){return columnTitle;}
	public int hashCode(){return columnTitle.hashCode();}
}
